﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

using Wicresoft.Shell.Core;

namespace Wicresoft.Shell.Logic
{
    public partial class ConnectInfos
    {
        private static String GetConnectInfosFileName()
        {
            return Path.Combine(Environment.CurrentDirectory, "ConnectInfos.xml");
        }

        private static ConnectInfos LoadConnectInfosFromFile()
        {
            String cnnInfosFileName = GetConnectInfosFileName();
            ConnectInfos cnnInfos = null;

            if (File.Exists(cnnInfosFileName))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(ConnectInfos));
                XmlReader xmlReader = null;
                FileStream xmlFStream = null;

                try
                {
                    xmlFStream = new FileStream(cnnInfosFileName, FileMode.Open, FileAccess.Read);
                    xmlReader = XmlReader.Create(xmlFStream);
                    cnnInfos = (ConnectInfos)serializer.Deserialize(xmlReader);
                }
                catch (InvalidOperationException)
                {
                    cnnInfos = null;
                }
                finally
                {
                    if (null != xmlReader)
                        xmlReader.Close();
                    if (null != xmlFStream)
                        xmlFStream.Close();
                }
            }

            return cnnInfos;
        }

        public static ConnectInfos LoadConnectInfos()
        {
            ConnectInfos cnnInfos = null;

            cnnInfos = LoadConnectInfosFromFile();
            if (null == cnnInfos)
                cnnInfos = new ConnectInfos();
            if (null == cnnInfos.ConnectInfo)
                cnnInfos.ConnectInfo = new ConnectInfoType[0];

            return cnnInfos;
        }

        public void SaveConnectInfos()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ConnectInfos));
            String cnnInfosFileName = GetConnectInfosFileName();
            FileStream xmlFStream = null;
            ConnectInfos preCnnInfos = null;

            preCnnInfos = LoadConnectInfosFromFile();
            try
            {
                if (null == preCnnInfos || DateTime.Equals(preCnnInfos.LastModifiedDate, this.LastModifiedDate))
                {
                    this.LastModifiedDate = DateTime.Now;
                    xmlFStream = new FileStream(cnnInfosFileName, FileMode.Create, FileAccess.Write);
                    serializer.Serialize(xmlFStream, this);
                }
            }
            catch (InvalidOperationException)
            { }
            finally
            {
                if (null != xmlFStream)
                    xmlFStream.Close();
            }
        }

        public void AddConnectInfo(ConnectInfoType cnnInfo)
        {
            List<ConnectInfoType> cnnInfoList = new List<ConnectInfoType>(this.ConnectInfo.Length + 1);

            cnnInfoList.Add(cnnInfo);
            cnnInfoList.AddRange(this.ConnectInfo.Where(c => !ConnectInfoType.Equals(c, cnnInfo)));
            this.ConnectInfo = cnnInfoList.ToArray();
        }

        public void RemoveConnectInfoByRef(ConnectInfoType cnnInfo)
        {
            this.ConnectInfo = this.ConnectInfo.Where(c => !Object.ReferenceEquals(c, cnnInfo)).ToArray();
        }
    }

    public partial class ConnectInfoType
    {
        private String passwordStrField;

        public ConnectInfoType()
        {
            serverNameField = null;
            userNameField = null;
            dBNameField = null;
            passwordField = null;
            passwordStrField = null;
        }

        public String GetPasswordStr()
        {
            if (null == passwordField)
                return null;
            
            if (null == passwordStrField)
            {
                if (!RijndaelCryptor.DecryptorString(passwordField, out passwordStrField))
                {
                    passwordField = null;
                    passwordStrField = null;
                }
            }

            return passwordStrField;
        }

        public void SetPassowrdStr(String pwdStr)
        {
            if (null == pwdStr)
            {
                passwordField = null;
                passwordStrField = null;

                return;
            }

            if (!String.Equals(passwordStrField, pwdStr))
            {
                passwordStrField = pwdStr;
                RijndaelCryptor.EncryptorString(passwordStrField, out passwordField);
            }
        }

        public override String ToString()
        {
            return String.Format("{0}/{1}({2})", ServerName, DBName, UserName);
        }

        public static Boolean Equals(ConnectInfoType a, ConnectInfoType b)
        {
            if (!String.Equals(a.ServerName, b.ServerName))
                return false;
            if (!String.Equals(a.DBName, b.DBName))
                return false;
            if (!String.Equals(a.UserName, b.UserName))
                return false;

            return true;
        }
    }
}
